package dynamic.methoddelegate

//给所有对象注入delegateCallsTo方法
Object.metaClass.delegateCallsTo = { Class... delegates->
    //遍历委托类集合,创建实例集合
    def listOfDelegates = delegates.collect { it.newInstance() }
    //目标对象调用不存在方法时,使用委托,拦截不存在方法调用
    delegate.metaClass.methodMissing= {String name,Object args->
        def entrust = listOfDelegates.find { it.metaClass.respondsTo(it,name,args)}
        if(entrust){
            //将方法缓存添加到目标方法,下次再调用直接就可以调用,不用再委托
            delegate.metaClass."$name" = {Object param->
                entrust.invokeMethod(name,param)
            }
            println "方法委托调用"  //只会第一次打印
            entrust.invokeMethod(name,args) //使用委托对象调用
        }else{
            throw new MissingMethodException(name,delegate.class,args)
        }
    }
}
def boss = new Boss()
boss.order()
boss.work()
boss.work()